package helper

import (
	"strings"
)

func Implode(glue string, pieces []string) string {
	return strings.Join(pieces, glue)
}

func Explode(delimiter, text string) []string {
	if len(delimiter) > len(text) {
		return strings.Split(delimiter, text)
	} else {
		return strings.Split(text, delimiter)
	}
}

func MbStrPos(haystack, needle string) int {
	index := strings.Index(haystack, needle)
	if index == -1 || index == 0 {
		return index
	}
	pos := 0
	total := 0
	reader := strings.NewReader(haystack)
	for {
		_, size, err := reader.ReadRune()
		if err != nil {
			return -1
		}
		total += size
		pos++
		// got it
		if total == index {
			return pos
		}
	}
}

func InArray(needle interface{}, hystack interface{}) bool {
	switch key := needle.(type) {
	case string:
		for _, item := range hystack.([]string) {
			if key == item {
				return true
			}
		}
	case int:
		for _, item := range hystack.([]int) {
			if key == item {
				return true
			}
		}
	case int64:
		for _, item := range hystack.([]int64) {
			if key == item {
				return true
			}
		}
	case uint64:
		for _, item := range hystack.([]uint64) {
			if key == item {
				return true
			}
		}
	default:
		return false
	}
	return false
}

func ArrayKeys(elements map[interface{}]interface{}) []interface{} {
	i, keys := 0, make([]interface{}, len(elements))
	for key, _ := range elements {
		keys[i] = key
		i++
	}
	return keys
}

func ArrayValues(elements map[interface{}]interface{}) []interface{} {
	i, vals := 0, make([]interface{}, len(elements))
	for _, val := range elements {
		vals[i] = val
		i++
	}
	return vals
}

func ArrayColumn(input map[string]map[string]interface{}, columnKey string) []interface{} {
	columns := make([]interface{}, 0, len(input))
	for _, val := range input {
		if v, ok := val[columnKey]; ok {
			columns = append(columns, v)
		}
	}
	return columns
}

func ArrayUnique(elements []interface{}) []interface{} {
	vals, exist := []interface{}{}, map[interface{}]int{}
	for key, val := range elements {
		if _, ok := exist[val]; !ok {
			vals = append(vals, val)
			exist[val] = key
		}
	}
	return vals
}

func HideStrWithStar(s string) string {
	str := []rune(s)
	strLen := len(str)
	switch strLen {
	case 0:
		return ""
	case 1:
		return string(str)
	case 2:
		return string(str[0]) + "*"
	default:
		return string(str[0]) + strings.Repeat("*", len(str[1:strLen-1])) + string(str[strLen-1:])
	}
}
